package exporter

import (
	"bytes"
	"context"
	"fmt"
	"log"
	"os/exec"
	"time"
        "strconv"
	"strings"
	"unicode"
)

func isLastCharDigit(s string) bool {
	if len(s) == 0 {
		return false
	}
	lastChar := rune(s[len(s)-1])
	return unicode.IsDigit(lastChar)
}

func ParseMemorySize(sizeStr string) (float64, error) {
	if isLastCharDigit(sizeStr){
		mem, _ := strconv.ParseFloat(sizeStr, 64)
		return mem, nil
	}
	s := strings.ToLower(strings.TrimSpace(sizeStr))

	// 支持的数字格式：123, 123.45, .5, 0.5
	var numPart, unitPart string
	for i, char := range s {
		if (char < '0' || char > '9') && char != '.' {
			numPart = s[:i]
			unitPart = s[i:]
			break
		}
	}

	if numPart == "" {
		numPart = s
	}

	value, err := strconv.ParseFloat(numPart, 64)
	if err != nil {
		return 0, fmt.Errorf("invalid number: %v", err)
	}

	// 清理单位字符串（去除空格等）
	unitPart = strings.TrimSpace(unitPart)

	switch unitPart {
	case "", "b":
		return float64(value), nil
	case "k", "kb":
		return float64(value), nil
	case "m", "mb":
		return float64(value * 1024), nil
	case "g", "gb":
		return float64(value * 1024 * 1024), nil
	case "t", "tb":
		return float64(value * 1024 * 1024 * 1024), nil
	default:
		return 0, fmt.Errorf("unknown unit: %s", unitPart)
	}
}

func RunCommand(timeoutSec int, command string) (string, error) {
	ctx, cancel := context.WithTimeout(
		context.Background(),
		time.Duration(timeoutSec)*time.Second,
	)
	defer cancel()

	cmd := exec.CommandContext(ctx, "bash", "-c", command)
	var out bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &out

	if err := cmd.Run(); err != nil {
		return out.String(), fmt.Errorf("exec failed: %v", err)
	}
	return out.String(), nil
}

func MemGet(NumLimit int) string {

	cmd := "top -w 256 -b -n 1 -c -o +%MEM | head " + fmt.Sprintf("-%d", NumLimit+7)

	outstr, err := RunCommand(3, cmd)
	// fmt.Printf("%v %v", outstr, err)
	if err != nil {
		log.Fatalf("MemGet error: %v", err)
	}
	return outstr

}

func CpuGet(NumLimit int) string {

	cmd := "top -w 256 -b -n 1 -c -o +%CPU | head " + fmt.Sprintf("-%d", NumLimit+7)

	outstr, err := RunCommand(3, cmd)
	//fmt.Printf("%v %v", outstr, err)
	if err != nil {
		log.Fatalf("MemGet error: %v", err)
	}
	return outstr

}
